package com.sgzn.sgpay.service.impl;

import com.sgzn.sgpay.enums.EnumDeviceState;
import com.sgzn.sgpay.model.request.SgsShopIncomeRequest;
import com.sgzn.sgpay.model.response.CurrentPageInfo;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.model.response.result.SgsShopIncomeResult;
import com.sgzn.sgpay.model.response.vo.ShopIncomeVo;
import com.sgzn.sgpay.persistence.dao.TBizOrderReadMapper;
import com.sgzn.sgpay.persistence.dao.TShopMapper;
import com.sgzn.sgpay.persistence.domain.TDevice;
import com.sgzn.sgpay.persistence.domain.TShop;
import com.sgzn.sgpay.persistence.domain.TShopExample;
import com.sgzn.sgpay.persistence.manager.DeviceDaoManager;
import com.sgzn.sgpay.persistence.manager.PresentReadManager;
import com.sgzn.sgpay.persistence.manager.ShopDaoManager;
import com.sgzn.sgpay.persistence.request.TBizOrderReadShopRequest;
import com.sgzn.sgpay.persistence.response.TBizOrderRead;
import com.sgzn.sgpay.persistence.response.TPresentRead;
import com.sgzn.sgpay.service.SgsShopIncomeService;
import com.sgzn.sgpay.service.support.SgsResponseUtil;
import com.sgzn.sgpay.util.PageCalculator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 门店经营分析服务实现类
 * @author huangsenguang
 * @version Id: SgsShopIncomeServiceImpl.java, v 0.1 2018/5/30 20:08 huangsenguang Exp $$
 */
@Slf4j
@Service
public class SgsShopIncomeServiceImpl implements SgsShopIncomeService {
    @Autowired
    private TShopMapper tShopMapper;

    @Resource
    private DeviceDaoManager deviceDaoManager;

    @Resource
    private TBizOrderReadMapper tBizOrderReadMapper;

    @Autowired
    private PresentReadManager presentReadManager;

    @Autowired
    private ShopDaoManager shopDaoManager;

    @Override
    public SgsResultResponse<SgsShopIncomeResult> queryInfo(SgsShopIncomeRequest request) {
        //分页查询
        TShopExample example = this.getTShopExampleByPage(request);
        int totalCount = this.tShopMapper.countByExample(example);//获取总数
        CurrentPageInfo pageInfo = PageCalculator.getPageInfo(totalCount, request.getPageQueryParam().getPageSize(),
                request.getPageQueryParam().getCurrentPage());
        StringBuffer clause = new StringBuffer();
        //加上起始和结束行号进行列表查询
        clause.append("updated_at,shop_id desc ");
        clause.append("limit ").append(pageInfo.getStartIndex()).
                append(",").append(pageInfo.getPageSize());
        example.setOrderByClause(clause.toString());
        //根据商户ID查询所有门店
        List<TShop> shoplist = tShopMapper.selectByExample(example);//门店信息 列表
        if (CollectionUtils.isEmpty(shoplist)) {
            return getEmptyResponse(totalCount, pageInfo);
        }
        List<String> shopIdList = new ArrayList<>(shoplist.size());
        Set<String> shopIdSet = new HashSet<>();
        for (TShop tShop : shoplist) {
            shopIdSet.add(tShop.getShopId());
        }
        shopIdList.addAll(shopIdSet);

        final int SIZE = shoplist.size();
        Map<String, String> shopMap = new HashMap<>(SIZE);
        Map<String, ShopIncomeVo> vosMap = new HashMap<>(SIZE);
        for (TShop tShop : shoplist) {
            shopMap.put(tShop.getShopId(), tShop.getShopName());//门店id、门店名称
            vosMap.put(tShop.getShopId(), new ShopIncomeVo());//初始化响应结果
        }
        //设备离线 总数
        List<TDevice> allDevices = this.deviceDaoManager.getAllDevices(shopIdList);
        Map<String, Integer> totalDeviceAmountMap = new HashMap<>();
        Map<String, Integer> offlineDeviceAmountMap = new HashMap<>();
        for (TShop tShop : shoplist) {
            totalDeviceAmountMap.put(tShop.getShopId(), 0);
            offlineDeviceAmountMap.put(tShop.getShopId(), 0);
        }
        List<String> deviceIdList = new ArrayList<>(allDevices.size());
        for (TDevice tDevice : allDevices) {
            deviceIdList.add(tDevice.getDeviceId());
            if (EnumDeviceState.OFFLINE.getStateCode().equals(tDevice.getState())) {
                Integer offline = offlineDeviceAmountMap.get(tDevice.getShopId());
                offline++;
                offlineDeviceAmountMap.put(tDevice.getShopId(), offline);
            }
            Integer total = totalDeviceAmountMap.get(tDevice.getShopId());
            total++;
            totalDeviceAmountMap.put(tDevice.getShopId(), total);
        }
        //在线支付map
        Map<String, BigDecimal> bizOrderMap = getOnlineAmountMap(shopIdList);


        List<TPresentRead> records = presentReadManager.gettPresentReads(request.getBeginTime(), request.getEndTime(), deviceIdList);
        Map<String, TPresentRead> presentRecordMap = new HashMap<>(SIZE);//礼品集合map
        for (TPresentRead record : records) {
            presentRecordMap.put(record.getShopId(), record);
        }

        SgsShopIncomeResult result = assembleSgsShopIncomeResult(totalCount, pageInfo, shoplist, SIZE, shopMap, vosMap, totalDeviceAmountMap, offlineDeviceAmountMap, bizOrderMap, presentRecordMap);
        return SgsResponseUtil.INSTANCE.success(result);
    }

    private SgsResultResponse<SgsShopIncomeResult> getEmptyResponse(int totalCount, CurrentPageInfo pageInfo) {
        SgsShopIncomeResult result = new SgsShopIncomeResult();
        result.setCurrentPage(pageInfo.getCurrentPage());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotalCount(totalCount);
        result.setTotalPage(pageInfo.getTotalPage());
        List<ShopIncomeVo> shopIncomeVoList = new ArrayList<>(0);
        result.setShopIncomeVoList(shopIncomeVoList);
        return SgsResponseUtil.INSTANCE.success(result);
    }

    /**
     * 组装结果
     * @param totalCount
     * @param pageInfo
     * @param shoplist
     * @param SIZE
     * @param shopMap
     * @param vosMap
     * @param totalDeviceAmountMap
     * @param offlineDeviceAmountMap
     * @param bizOrderMap
     * @param presentRecordMap
     * @return
     */
    private SgsShopIncomeResult assembleSgsShopIncomeResult(int totalCount, CurrentPageInfo pageInfo, List<TShop> shoplist, int SIZE, Map<String, String> shopMap, Map<String, ShopIncomeVo> vosMap, Map<String, Integer> totalDeviceAmountMap, Map<String, Integer> offlineDeviceAmountMap, Map<String, BigDecimal> bizOrderMap, Map<String, TPresentRead> presentRecordMap) {
        SgsShopIncomeResult result = new SgsShopIncomeResult();
        result.setCurrentPage(pageInfo.getCurrentPage());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotalCount(totalCount);
        result.setTotalPage(pageInfo.getTotalPage());
        List<ShopIncomeVo> shopIncomeVoList = new ArrayList<>(SIZE);
        for (TShop tShop : shoplist) {
            String shopId = tShop.getShopId();
            ShopIncomeVo shopIncomeVo = vosMap.get(shopId);
            TPresentRead tPresentRead = presentRecordMap.get(shopId);
            int totalPresentBalance = 0;
            if (tPresentRead != null) {
                totalPresentBalance = tPresentRead.getPresentPrice() * tPresentRead.getPresentAmount();
                shopIncomeVo.setConsumePresentAmount(tPresentRead.getPresentAmount());
            }
            shopIncomeVo.setShopId(shopId);
            shopIncomeVo.setShopName(shopMap.get(shopId));
            shopIncomeVo.setOfflineDeviceAmount(offlineDeviceAmountMap.get(shopId));
            shopIncomeVo.setTotalDeviceAmount(totalDeviceAmountMap.get(shopId));
            shopIncomeVo.setOnlineAmount(bizOrderMap.get(shopId));
            shopIncomeVo.setConsumePresentBalance(totalPresentBalance);
            if (bizOrderMap.get(shopId) != null) {
                shopIncomeVo.setTotalIncome(bizOrderMap.get(shopId).add(new BigDecimal(totalPresentBalance)));//门店收益总计
            } else {
                shopIncomeVo.setTotalIncome(new BigDecimal(totalPresentBalance));//门店收益总计
            }
            shopIncomeVoList.add(shopIncomeVo);
        }
        result.setShopIncomeVoList(shopIncomeVoList);
        return result;
    }

    /**
     * 获取查询对象
     * @param request
     * @return
     */
    private TShopExample getTShopExampleByPage(SgsShopIncomeRequest request){
        TShopExample countExample = new TShopExample();
        TShopExample.Criteria cra = countExample.createCriteria();
        if (request.getBeginTime() != null && request.getEndTime() != null) {
            cra.andUpdatedAtBetween(request.getBeginTime(), request.getEndTime());
        }
        if (CollectionUtils.isEmpty(request.getShopIdList())) {
            List<String> shopIdList = this.shopDaoManager.getShopIdList(request.getMchId());
            cra.andShopIdIn(shopIdList);
        } else {
            cra.andShopIdIn(request.getShopIdList());//页面传过来有值
        }
        return countExample;
    }

    /**
     * 在线支付
     * @param shopIdList
     * @return
     */
    private Map<String,BigDecimal> getOnlineAmountMap(List<String> shopIdList) {
        TBizOrderReadShopRequest tBizOrderReadShopRequest = new TBizOrderReadShopRequest();
        tBizOrderReadShopRequest.setShopIdList(shopIdList); //注意使用判断后的 而不是请求类里的， 请求类里的可能为空
        List<TBizOrderRead> respList = tBizOrderReadMapper.queryByShopIds(tBizOrderReadShopRequest);
        Map<String, BigDecimal> bizOrderMap = new HashMap<>(respList.size());
        for (TBizOrderRead tBizOrderRead : respList) {
            bizOrderMap.put(tBizOrderRead.getShopId(), tBizOrderRead.getSumAmount());
        }
        return bizOrderMap;
    }
}

